import json
import urllib.request
from typing import List


class BaseElement:
    def __init__(self, tag: str):
        self.tag = tag


class HrElement(BaseElement):
    def __init__(self):
        tag = "hr"
        super().__init__(tag)


class TextElement(BaseElement):
    def __init__(self, content: str):
        super().__init__("div")
        self.text = {"content": content, "tag": "plain_text"}


class AtElement(BaseElement):
    def __init__(self, content: str):
        super().__init__("div")
        self.text = {"content": content, "tag": "lark_md"}


class MarkdownElement(BaseElement):
    def __init__(self, content):
        tag = "markdown"
        super().__init__(tag)
        self.content = str(content)


class ColumnElement(BaseElement):
    def __init__(self, markdown_content: str, width="weighted", weight=1, vertical_align="top"):
        tag = "column"
        super().__init__(tag)
        self.width = width
        self.weight = weight
        self.vertical_align = vertical_align
        self.elements = [MarkdownElement(markdown_content)]


class ColumnSetElement(BaseElement):
    def __init__(self, columns_list=None, background_style="grey", flex_mode="none"):
        tag = "column_set"
        super().__init__(tag)
        self.flex_mode = flex_mode
        self.background_style = background_style
        if columns_list is None:
            columns_list = []
        self.columns = columns_list

    def append(self, element: ColumnElement):
        self.columns.append(element)


class Card:
    def __init__(self, header_content: str, elements: List[BaseElement], template="green"):
        self.elements = elements
        self.config = {"wide_screen_mode": True}
        self.header = {
            "template": template,
            "title": {
                "content": header_content,
                "tag": "plain_text"
            }
        }


class MarkdownCard:
    def __init__(self, card: Card):
        self.msg_type = "interactive"
        self.card = card


def object_to_dict(obj):
    if isinstance(obj, List) or isinstance(obj, tuple):
        return [object_to_dict(item) for item in obj]
    elif isinstance(obj, dict):
        return {key: object_to_dict(value) for key, value in obj.items()}
    elif hasattr(obj, "__dict__"):
        return object_to_dict(obj.__dict__)
    else:
        return obj


def send(card: Card, url: str):
    markdown_card = MarkdownCard(card=card)
    data = json.dumps(object_to_dict(markdown_card)).encode('utf-8')
    print(data)
    response = urllib.request.urlopen(
        urllib.request.Request(url=url, data=data, headers={"Content-Type": "application/json"})
    ).read()
    print(response)


def send_fail(header: str, content: str, url: str):
    elements = []
    if content is not None and content != '':
        elements.append(MarkdownElement(content=content))
    send(Card(header, elements, "red"), url)
